package fr.cephb.dbsnptools;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import fr.cephb.io.IOUtils;
import fr.cephb.util.AbstractCmdLine;
import fr.cephb.util.StringUtils;

public class Export
	extends AbstractCmdLine
	{
	private int mode=1;
	private int flanking_size=-1;
	
	private Export()
		{
		
		}
	@Override
	protected void usage(PrintStream out)
		{
		super.usage(out);
		System.out.println(" -f <integer> restrict flanking size for mode:2 and 4");
		System.out.println(" -m <integer = mode> default:1");
		System.out.println("      1: rs seq5 obs seq3 num-handles handles");
		System.out.println("      2: one fasta sequence for each side");
		System.out.println("      3: for each map : rs observed position");
		System.out.println("      4: rs /left/right");
		System.out.println("      5: same as 3 but print FxnSet as JSON");
		}
	@Override
	protected int processArg(String[] args, int optind)
		{
		if(args[optind].equals("-m"))
			{
			this.mode= Integer.parseInt(args[++optind]);
			return optind;
			}
		else if(args[optind].equals("-f"))
			{
			this.flanking_size= Integer.parseInt(args[++optind]);
			return optind;
			}
		return super.processArg(args, optind);
		}
	private void start()
		{
		
		}
	
	private void end()
		{
		
		}
	
	private void delim()
		{
		System.out.print('\t');
		}
	
	private void print(SnpRecord rec)
		{
		switch(this.mode)
			{
			case 2:
					{
					if(this.flanking_size<=0)
						{
						System.out.println(">L"+rec.getRsId());
						System.out.println(rec.getSeq5());
						System.out.println(">R"+rec.getRsId());
						System.out.println(rec.getSeq3());
						}
					else
						{
						System.out.println(">L"+rec.getRsId());
						System.out.println(rec.getSeq5(this.flanking_size));
						System.out.println(">R"+rec.getRsId());
						System.out.println(rec.getSeq3(this.flanking_size));
						}
					break;
					}
			case 3:
			case 5:
					{
					for(SnpRecord.MapLoc loc:rec.getLocations())
						{
						System.out.print("rs"+rec.getRsId());
						delim();
						System.out.print(rec.getObserved());
						delim();
						System.out.print(loc.groupLabel);
						delim();
						System.out.print(loc.genomeBuild);
						delim();
						System.out.print(loc.chromosome);
						delim();
						System.out.print(loc.orient);
						delim();
						System.out.print(loc.physMapInt);
						
						if(this.mode==5)
							{
							delim();
							System.out.print("[");
							for(int i=0; i< loc.fxn.size();++i)
								{
								if(i!=0) System.out.print(",");
								System.out.print(loc.fxn.get(i).toJSON());
								}
							System.out.print("]");
							}
					
						System.out.println();
						}
					break;
					}
			case 4:
			
					{
					System.out.print("rs"+rec.getRsId());
					delim();
					System.out.print(rec.getSeq5(this.flanking_size));
					delim();
					System.out.print(rec.getSeq3(this.flanking_size));
					
					
					System.out.println();
					break;
					}
			default:
				{
				System.out.print(rec.getRsId());
				System.out.print("\t");
				System.out.print(rec.getSeq5());
				System.out.print("\t");
				System.out.print(rec.getObserved());
				System.out.print("\t");
				System.out.print(rec.getSeq3());
				System.out.print("\t");
				System.out.print(rec.getHandles().size());
				System.out.print("\t");
				System.out.print(StringUtils.join(rec.getHandles(),"|"));
				System.out.println();
				break;
				}
			}
		}
	
	private void parse(InputStream in)
		throws IOException,SAXException
		{
		SnpHandler handler=new SnpHandler()
			{
			@Override
			public void found(SnpRecord rec)
				{
				print(rec);
				}
			};
		handler.parse(new InputSource(in));
		}
	
	public static void main(String[] args)
		{
		try
			{
			Export app=new Export();
			int optind= app.processArgs(args);
			if(optind==args.length)
				{
				System.err.println("No arguments");
				return;
				}
			app.start();                   
            while(optind< args.length)
                    {
                  	InputStream r=IOUtils.openInputStream(args[optind++]);
                    app.parse(r);
                    r.close();
                    }
            app.end();                  
			}
		catch (Exception e)
			{
			e.printStackTrace();
			}
		}
	
	}
